home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Workbench Add-On
/
Workbench Add-On - Volume 1.iso
/
BBS-Archive
/
Comm
/
term-source.lha
/
Extras
/
Source
/
term-Source.lha
/
termTranslate.c
< prev
next >
Wrap
C/C++ Source or Header
|
1995-02-07
|
23KB
|
1,125 lines
/*
** termTranslate.c
**
** Character translation support routines
**
** Copyright © 1990-1995 by Olaf `Olsen' Barthel
** All Rights Reserved
*/
#include "termGlobal.h"
/* Translation chunk header types. */
enum { TYPE_NONE, TYPE_SEND, TYPE_RECEIVE };
/* Master translation table entry types. */
enum { TRANSLATION_VERBATIM, TRANSLATION_IGNORE, TRANSLATION_OTHER };
/* Symbolic names for character codes. */
STATIC struct { STRPTR Name; UBYTE Value; } CodeTab[44] =
{
{ "NUL", 0 },
{ "SOH", 1 },
{ "STX", 2 },
{ "ETX", 3 },
{ "EOT", 4 },
{ "ENQ", 5 },
{ "ACK", 6 },
{ "BEL", 7 },
{ "BS", 8 },
{ "HT", 9 },
{ "LF", 10 },
{ "VT", 11 },
{ "FF", 12 },
{ "CR", 13 },
{ "SO", 14 },
{ "SI", 15 },
{ "DLE", 16 },
{ "DC1", 17 },
{ "DC2", 18 },
{ "DC3", 19 },
{ "DC4", 20 },
{ "NAK", 21 },
{ "SYN", 22 },
{ "ETB", 23 },
{ "CAN", 24 },
{ "EM", 25 },
{ "SUB", 26 },
{ "ESC", 27 },
{ "FS", 28 },
{ "GS", 29 },
{ "RS", 30 },
{ "US", 31 },
{ "SP", 32 },
{ "DEL", 127 },
{ "SS2", 142 },
{ "SS3", 143 },
{ "DCS", 144 },
{ "CSI", 155 },
{ "ST", 156 },
{ "OSC", 157 },
{ "PM", 158 },
{ "APC", 159 },
{ "NBS", 160 },
{ "SHY", 173 }
};
/* TranslateSetup():
*
* Set up for buffer translation.
*/
VOID __regargs
TranslateSetup(struct TranslationHandle *Handle,STRPTR SourceBuffer,LONG SourceLen,STRPTR DestinationBuffer,LONG DestinationLen,struct TranslationEntry **Table)
{
Handle -> LocalBuffer = NULL;
Handle -> LocalLen = 0;
Handle -> SourceBuffer = SourceBuffer;
Handle -> SourceLen = SourceLen;
Handle -> DestinationBuffer = DestinationBuffer;
Handle -> DestinationLen = DestinationLen;
Handle -> Table = Table;
}
/* TranslateBuffer(struct TranslationHandle *Handle):
*
* Translate buffer contents according to
* translation table contents.
*/
LONG __regargs
TranslateBuffer(struct TranslationHandle *Handle)
{
register STRPTR Data = Handle -> DestinationBuffer;
register LONG BytesWritten = 0;
register struct TranslationEntry *Entry;
/* Are we to return any translated data? */
while(Handle -> LocalLen && BytesWritten < Handle -> DestinationLen)
{
/* Decrement number of bytes in buffer. */
Handle -> LocalLen--;
/* Return next character. */
*Data++ = *Handle -> LocalBuffer++;
/* Add another byte. */
BytesWritten++;
}
/* Loop until done. */
while(Handle -> SourceLen && BytesWritten < Handle -> DestinationLen)
{
/* Another byte eaten. */
Handle -> SourceLen--;
/* Get table entry. */
if(Entry = Handle -> Table[*Handle -> SourceBuffer++])
{
/* Copy to local data area. */
Handle -> LocalBuffer = Entry -> String;
Handle -> LocalLen = Entry -> Len;
/* Translate the data. */
while(Handle -> LocalLen && BytesWritten < Handle -> DestinationLen)
{
/* Decrement number of bytes in buffer. */
Handle -> LocalLen--;
/* Return next character. */
*Data++ = *Handle -> LocalBuffer++;
/* Add another byte. */
BytesWritten++;
}
}
}
return(BytesWritten);
}
/* NameToCode(STRPTR Name):
*
* Translate a symbolic character code name of numeral.
*/
UBYTE __regargs
NameToCode(STRPTR Name)
{
WORD i;
for(i = 0 ; i < 44 ; i++)
{
if(!Stricmp(CodeTab[i] . Name,Name))
return(CodeTab[i] . Value);
}
return((UBYTE)Atol(Name));
}
/* CodeToName(UBYTE Code):
*
* Translate a character code into a symbolic
* name or numeral.
*/
STRPTR __regargs
CodeToName(UBYTE Code)
{
STATIC UBYTE Name[6];
WORD i;
for(i = 0 ; i < 44 ; i++)
{
if(CodeTab[i] . Value == Code)
return(CodeTab[i] . Name);
}
SPrintf(Name,"%03ld",Code);
return(Name);
}
/* FreeTranslationTable(struct TranslationEntry **Table):
*
* Free a character translation table.
*/
VOID __regargs
FreeTranslationTable(struct TranslationEntry **Table)
{
WORD i;
for(i = 0 ; i < 256 ; i++)
{
if(Table[i])
FreeTranslationEntry(Table[i]);
}
FreeVecPooled(Table);
}
/* AllocTranslationTable():
*
* Allocate a character translation table.
*/
struct TranslationEntry **
AllocTranslationTable()
{
return((struct TranslationEntry **)AllocVecPooled(sizeof(struct TranslationEntry *) * 256,MEMF_ANY|MEMF_CLEAR));
}
/* FreeTranslationEntry(struct TranslationEntry *Entry):
*
* Free a character translation table entry.
*/
VOID __regargs
FreeTranslationEntry(struct TranslationEntry *Entry)
{
FreeVecPooled(Entry);
}
/* TranslateString(STRPTR From,STRPTR To):
*
* Translate a string to contain control codes
* into a string to contain the real codes.
*/
LONG __regargs
TranslateString(STRPTR From,STRPTR To)
{
BYTE GotControl = FALSE,
GotEscape = FALSE;
LONG Len = strlen(From),
Count = 0,
i;
for(i = 0 ; i < Len ; i++)
{
if(!GotControl && !GotEscape)
{
if(From[i] == '\\')
{
GotControl = TRUE;
continue;
}
if(From[i] == '^')
{
GotEscape = TRUE;
continue;
}
To[Count++] = From[i];
}
else
{
if(GotEscape)
{
if(ToUpper(From[i]) >= 'A' && ToUpper(From[i]) <= '_')
To[Count++] = ToUpper(From[i]) - '@';
else
To[Count++] = From[i];
GotEscape = FALSE;
}
else
{
if(GotControl)
{
switch(ToUpper(From[i]))
{
/* These macro commands are plainly
* ignored.
*/
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
break;
/* These are macro commands and
* not supported.
*/
case 'A':
case 'C':
case 'D':
case 'G':
case 'H':
case 'I':
case 'P':
case 'U':
case 'X':
To[Count++] = '\\';
To[Count++] = From[i];
break;
/* Translate code. */
case '*':
i++;
while(i < Len && From[i] == ' ')
i++;
if(i < Len)
{
UBYTE DummyBuffer[5],j = 0,Char;
if(From[i] >= '0' && From[i] <= '9')
{
while(j < 3 && i < Len)
{
Char = From[i++];
if(Char >= '0' && Char <= '9')
DummyBuffer[j++] = Char;
else
{
i--;
break;
}
}
}
else
{
while(j < 4 && i < Len)
{
Char = ToLower(From[i++]);
if((Char >= '0' && Char <= '9') || (Char >= 'a' && Char <= 'z'))
DummyBuffer[j++] = Char;
else
{
i--;
break;
}
}
}
DummyBuffer[j] = 0;
To[Count++] = NameToCode(DummyBuffer);
}
i--;
break;
/* This is a backspace. */
case 'B':
To[Count++] = '\b';
break;
/* This is a form feed. */
case 'F':
To[Count++] = '\f';
break;
/* This is a line feed. */
case 'N':
To[Count++] = '\n';
break;
/* This is a carriage return. */
case 'R':
To[Count++] = '\r';
break;
/* This is a tab. */
case 'T':
To[Count++] = '\t';
break;
/* Produce the escape character. */
case 'E':
To[Count++] = ESC;
break;
/* Stuff the character into the buffer. */
default:
To[Count++] = From[i];
break;
}
GotControl = FALSE;
}
}
}
}
return(Count);
}
/* AllocTranslationEntry(STRPTR String):
*
* Allocate a character translation table entry.
*/
struct TranslationEntry * __regargs
AllocTranslationEntry(STRPTR String)
{
LONG Count = TranslateString(String,SharedBuffer);
if(Count > 0)
{
struct TranslationEntry *Entry;
UBYTE Type;
if(Count > 1)
{
Type = TRANSLATE_STRING;
if(Entry = (struct TranslationEntry *)AllocVecPooled(sizeof(struct TranslationEntry) + Count + 1,MEMF_ANY|MEMF_CLEAR))
{
Entry -> String = (STRPTR)(Entry + 1);
memcpy(Entry -> String,SharedBuffer,Count);
}
}
else
{
Type = TRANSLATE_SINGLE;
if(Entry = (struct TranslationEntry *)AllocVecPooled(sizeof(struct TranslationEntry),MEMF_ANY|MEMF_CLEAR))
{
Entry -> String = &Entry -> Extra;
Entry -> Extra = SharedBuffer[0];
}
}
if(Entry)
{
Entry -> Type = Type;
Entry -> Len = Count;
return(Entry);
}
}
return(NULL);
}
/* FillTranslationTable(struct TranslationEntry **Table):
*
* Fill the translation table with defaults.
*/
BYTE __regargs
FillTranslationTable(struct TranslationEntry **Table)
{
BYTE Success = TRUE;
WORD i;
for(i = 0 ; Success && i < 256 ; i++)
{
if(Table[i] = (struct TranslationEntry *)AllocVecPooled(sizeof(struct TranslationEntry),MEMF_ANY|MEMF_CLEAR))
{
Table[i] -> Type = TRANSLATE_SINGLE;
Table[i] -> String = &Table[i] -> Extra;
Table[i] -> Extra = i;
Table[i] -> Len = 1;
}
else
Success = FALSE;
}
if(!Success)
{
for(i = 0 ; i < 256 ; i++)
{
if(Table[i])
{
FreeVecPooled(Table[i]);
Table[i] = NULL;
}
}
}
return(Success);
}
/* IsStandardTable(struct TranslationEntry **Table):
*
* Checks a translation table to see if it contains
* standard data.
*/
BYTE __regargs
IsStandardTable(struct TranslationEntry **Table)
{
WORD i;
for(i = 0 ; i < 256 ; i++)
{
if(Table[i])
{
if(Table[i] -> Type != TRANSLATE_SINGLE || Table[i] -> Len != 1 || Table[i] -> String[0] != i)
return(FALSE);
}
else
return(FALSE);
}
return(TRUE);
}
/* TranslateBack(STRPTR From,LONG Len,STRPTR To):
*
* Translate a precompiled translation string
* back.
*/
VOID __regargs
TranslateBack(STRPTR From,LONG Len,STRPTR To)
{
STATIC char TypeTable[256] =
{
1 , 1 , 1 , 1 , 1 , 1 , 1 ,1 ,'b','t','n', 1 ,'f','r', 1 , 1,
1 , 1 , 1 , 1 , 1 , 1 , 1 ,1 , 1 , 1 , 1 ,'e', 1 , 1 , 1 , 1,
2 , 2 , 2 , 2 , 2 , 2 , 2 ,2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2,
2 , 2 , 2 , 2 , 2 , 2 , 2 ,2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2,
2 , 2 , 2 , 2 , 2 , 2 , 2 ,2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2,
2 , 2 , 2 , 2 , 2 , 2 , 2 ,2 , 2 , 2 , 2 , 2 ,'\\',2 , 2 , 2,
2 , 2 , 2 , 2 , 2 , 2 , 2 ,2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2,
2 , 2 , 2 , 2 , 2 , 2 , 2 ,2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 0,
0 , 0 , 0 , 0 , 0 , 0 , 0 ,0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0,
0 , 0 , 0 , 0 , 0 , 0 , 0 ,0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0,
0 , 2 , 2 , 2 , 2 , 2 , 2 ,2 , 2 , 2 , 2 , 2 , 2 , 0 , 2 , 2,
2 , 2 , 2 , 2 , 2 , 2 , 2 ,2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2,
2 , 2 , 2 , 2 , 2 , 2 , 2 ,2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2,
2 , 2 , 2 , 2 , 2 , 2 , 2 ,2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2,
2 , 2 , 2 , 2 , 2 , 2 , 2 ,2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2,
2 , 2 , 2 , 2 , 2 , 2 , 2 ,2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2
};
STRPTR Buffer;
LONG i,j,BufLen;
for(i = j = 0 ; i < Len ; i++)
{
switch(TypeTable[From[i]])
{
case 0: To[j++] = '\\';
To[j++] = '*';
Buffer = CodeToName(From[i]);
BufLen = strlen(Buffer);
memcpy(&To[j],Buffer,BufLen);
j += BufLen;
break;
case 1: To[j++] = '^';
To[j++] = From[i] + '@';
break;
case 2: To[j++] = From[i];
break;
default:To[j++] = '\\';
To[j++] = TypeTable[From[i]];
break;
}
}
To[j] = 0;
}
/* SaveTranslationTables():
*
* Save a character translation table to a file.
*/
BYTE __regargs
SaveTranslationTables(STRPTR Name,struct TranslationEntry **SendTable,struct TranslationEntry **ReceiveTable)
{
BYTE Success = FALSE,
DoIt = FALSE;
WORD i;
LONG Error = 0;
for(i = 0 ; !DoIt && i < 256 ; i++)
{
if(SendTable[i] || ReceiveTable[i])
DoIt = TRUE;
}
if(DoIt)
{
struct IFFHandle *Handle;
UBYTE MasterTable[256];
for(i = 0 ; i < 256 ; i++)
{
if(SendTable[i])
{
if(SendTable[i] -> Type == TRANSLATE_SINGLE && SendTable[i] -> Len == 1 && SendTable[i] -> String[0] == i)
MasterTable[i] = TRANSLATION_VERBATIM;
else
MasterTable[i] = TRANSLATION_OTHER;
}
else
MasterTable[i] = TRANSLATION_IGNORE;
if(ReceiveTable[i])
{
if(ReceiveTable[i] -> Type == TRANSLATE_SINGLE && ReceiveTable[i] -> Len == 1 && ReceiveTable[i] -> String[0] == i)
MasterTable[i] |= TRANSLATION_VERBATIM << 4;
else
MasterTable[i] |= TRANSLATION_OTHER << 4;
}
else
MasterTable[i] |= TRANSLATION_IGNORE << 4;
}
if(Handle = AllocIFF())
{
if(Handle -> iff_Stream = Open(Name,MODE_NEWFILE))
{
InitIFFasDOS(Handle);
if(!(Error = OpenIFF(Handle,IFFF_WRITE)))
{
if(!(Error = PushChunk(Handle,ID_TERM,ID_CAT,IFFSIZE_UNKNOWN)))
{
if(!(Error = PushChunk(Handle,ID_TERM,ID_FORM,IFFSIZE_UNKNOWN)))
{
if(!(Error = PushChunk(Handle,0,ID_VERS,IFFSIZE_UNKNOWN)))
{
struct TermInfo TermInfo;
TermInfo . Version = CONFIG_FILE_VERSION;
TermInfo . Revision = CONFIG_FILE_REVISION;
if(WriteChunkRecords(Handle,&TermInfo,sizeof(struct TermInfo),1))
{
if(!(Error = PopChunk(Handle)))
{
if(!(Error = PushChunk(Handle,0,ID_TRNS,256)))
{
if(WriteChunkBytes(Handle,MasterTable,256) == 256)
{
if(!(Error = PopChunk(Handle)))
{
if(!(Error = PopChunk(Handle)))
{
struct TranslationHeader Header;
Success = TRUE;
for(i = 0 ; Success && i < 256 ; i++)
{
if(SendTable[i] && (MasterTable[i] & 0xF) == TRANSLATION_OTHER)
{
Header . Type = SendTable[i] -> Type;
Header . Len = SendTable[i] -> Len;
Header . Code = i;
Header . Pad = 0;
if(!(Error = PushChunk(Handle,ID_TERM,ID_FORM,IFFSIZE_UNKNOWN)))
{
if(!(Error = PushChunk(Handle,0,ID_SEND,sizeof(struct TranslationHeader))))
{
if(WriteChunkRecords(Handle,&Header,sizeof(struct TranslationHeader),1))
{
if(!(Error = PopChunk(Handle)))
{
if(!(Error = PushChunk(Handle,0,ID_CHRS,SendTable[i] -> Len)))
{
if(WriteChunkRecords(Handle,SendTable[i] -> String,SendTable[i] -> Len,1))
{
if(Error = PopChunk(Handle))
Success = FALSE;
}
else
{
Error = IoErr();
Success = FALSE;
}
}
}
else
Success = FALSE;
}
else
{
Error = IoErr();
Success = FALSE;
}
}
if(Success)
{
if(PopChunk(Handle))
Success = FALSE;
}
}
else
Success = FALSE;
}
if(ReceiveTable[i] && (MasterTable[i] >> 4) == TRANSLATION_OTHER)
{
Header . Type = ReceiveTable[i] -> Type;
Header . Len = ReceiveTable[i] -> Len;
Header . Code = i;
Header . Pad = 0;
if(!(Error = PushChunk(Handle,ID_TERM,ID_FORM,IFFSIZE_UNKNOWN)))
{
if(!(Error = PushChunk(Handle,0,ID_RECV,sizeof(struct TranslationHeader))))
{
if(WriteChunkRecords(Handle,&Header,sizeof(struct TranslationHeader),1))
{
if(!(Error = PopChunk(Handle)))
{
if(!(Error = PushChunk(Handle,0,ID_CHRS,ReceiveTable[i] -> Len)))
{
if(WriteChunkRecords(Handle,ReceiveTable[i] -> String,ReceiveTable[i] -> Len,1))
{
if(Error = PopChunk(Handle))
Success = FALSE;
}
else
{
Error = IoErr();
Success = FALSE;
}
}
}
else
Success = FALSE;
}
else
{
Error = IoErr();
Success = FALSE;
}
}
if(Success)
{
if(Error = PopChunk(Handle))
Success = FALSE;
}
}
else
Success = FALSE;
}
}
}
}
}
else
Error = IoErr();
}
}
}
else
Error = IoErr();
}
}
if(Success)
{
if(PopChunk(Handle))
Success = FALSE;
}
}
CloseIFF(Handle);
}
Close(Handle -> iff_Stream);
if(Success)
AddProtection(Name,FIBF_EXECUTE);
else
DeleteFile(Name);
}
else
Error = IoErr();
FreeIFF(Handle);
}
else
Error = ERR_NO_MEM;
}
if(Error)
SetIoErr(Error);
return(Success);
}
/* LoadTranslationTable()s:
*
* Load a translation table from a file.
*/
BYTE __regargs
LoadTranslationTables(STRPTR Name,struct TranslationEntry **SendTable,struct TranslationEntry **ReceiveTable)
{
STATIC ULONG Stops[5 * 2] =
{
ID_TERM, ID_VERS,
ID_TERM, ID_TRNS,
ID_TERM, ID_SEND,
ID_TERM, ID_RECV,
ID_TERM, ID_CHRS
};
struct IFFHandle *Handle;
BYTE Success = FALSE;
WORD i;
UBYTE MasterTable[256];
BYTE GotMasterTable = FALSE;
LONG Error;
if(Handle = AllocIFF())
{
if(Handle -> iff_Stream = Open(Name,MODE_OLDFILE))
{
InitIFFasDOS(Handle);
if(!(Error = OpenIFF(Handle,IFFF_READ)))
{
if(!(Error = StopChunks(Handle,(LONG *)Stops,5)))
{
struct ContextNode *Chunk;
struct TermInfo TermInfo;
struct TranslationHeader Header;
BYTE LastType = TYPE_NONE;
Success = TRUE;
while(Success && !ParseIFF(Handle,IFFPARSE_SCAN))
{
Chunk = CurrentChunk(Handle);
switch(Chunk -> cn_ID)
{
case ID_VERS:
if(ReadChunkBytes(Handle,&TermInfo,sizeof(struct TermInfo)) == sizeof(struct TermInfo))
{
if(TermInfo . Version > CONFIG_FILE_VERSION || (TermInfo . Version == CONFIG_FILE_VERSION && TermInfo . Revision > CONFIG_FILE_REVISION))
{
Error = ERR_OUTDATED;
Success = FALSE;
}
}
else
{
Error = IoErr();
Success = FALSE;
}
break;
case ID_TRNS:
if(ReadChunkBytes(Handle,MasterTable,256) == 256)
GotMasterTable = TRUE;
else
{
Error = IoErr();
Success = FALSE;
}
break;
case ID_SEND:
if(LastType != TYPE_NONE)
Success = FALSE;
else
{
if(!ReadChunkRecords(Handle,&Header,MIN(sizeof(struct TranslationHeader),Chunk -> cn_Size),1))
{
Error = IoErr();
Success = FALSE;
}
else
LastType = TYPE_SEND;
}
break;
case ID_RECV:
if(LastType != TYPE_NONE)
{
Error = IFFERR_MANGLED;
Success = FALSE;
}
else
{
if(!ReadChunkRecords(Handle,&Header,MIN(sizeof(struct TranslationHeader),Chunk -> cn_Size),1))
{
Success = FALSE;
Error = IoErr();
}
else
LastType = TYPE_RECEIVE;
}
break;
case ID_CHRS:
if(LastType == TYPE_NONE)
{
Error = IFFERR_MANGLED;
Success = FALSE;
}
else
{
if(ReadChunkRecords(Handle,SharedBuffer,Header . Len,1))
{
struct TranslationEntry *Entry;
if(Header . Type == TRANSLATE_SINGLE)
{
if(Entry = (struct TranslationEntry *)AllocVecPooled(sizeof(struct TranslationEntry),MEMF_ANY|MEMF_CLEAR))
{
Entry -> String = &Entry -> Extra;
Entry -> Extra = SharedBuffer[0];
}
}
else
{
if(Entry = (struct TranslationEntry *)AllocVecPooled(sizeof(struct TranslationEntry) + Header . Len + 1,MEMF_ANY|MEMF_CLEAR))
{
Entry -> String = (STRPTR)(Entry + 1);
memcpy(Entry -> String,SharedBuffer,Header . Len);
}
}
if(Entry)
{
Entry -> Type = Header . Type;
Entry -> Len = Header . Len;
if(LastType == TYPE_SEND)
SendTable[Header . Code] = Entry;
else
ReceiveTable[Header . Code] = Entry;
LastType = TYPE_NONE;
}
else
{
Error = ERR_NO_MEM;
Success = FALSE;
}
}
else
{
Error = IoErr();
Success = FALSE;
}
}
break;
}
}
}
CloseIFF(Handle);
}
Close(Handle -> iff_Stream);
}
else
Error = IoErr();
FreeIFF(Handle);
}
else
Error = ERR_NO_MEM;
if(Success && GotMasterTable)
{
struct TranslationEntry *Entry;
for(i = 0 ; i < 256 ; i++)
{
if((MasterTable[i] & 0xF) == TRANSLATION_VERBATIM)
{
if(Entry = (struct TranslationEntry *)AllocVecPooled(sizeof(struct TranslationEntry),MEMF_ANY|MEMF_CLEAR))
{
Entry -> Type = TRANSLATE_SINGLE;
Entry -> String = &Entry -> Extra;
Entry -> Extra = i;
Entry -> Len = 1;
SendTable[i] = Entry;
}
else
{
Error = ERR_NO_MEM;
Success = FALSE;
break;
}
}
if((MasterTable[i] >> 4) == TRANSLATION_VERBATIM)
{
if(Entry = (struct TranslationEntry *)AllocVecPooled(sizeof(struct TranslationEntry),MEMF_ANY|MEMF_CLEAR))
{
Entry -> Type = TRANSLATE_SINGLE;
Entry -> String = &Entry -> Extra;
Entry -> Extra = i;
Entry -> Len = 1;
ReceiveTable[i] = Entry;
}
else
{
Error = ERR_NO_MEM;
Success = FALSE;
break;
}
}
}
}
if(!Success)
{
for(i = 0 ; i < 256 ; i++)
{
if(SendTable[i])
{
FreeTranslationEntry(SendTable[i]);
SendTable[i] = NULL;
}
if(ReceiveTable[i])
{
FreeTranslationEntry(ReceiveTable[i]);
ReceiveTable[i] = NULL;
}
}
}
if(Error)
SetIoErr(Error);
return(Success);
}